package org.six11.ss.client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.List;
import java.util.TreeSet;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;

import org.six11.ss.shared.Message;
import org.six11.util.Debug;
import org.six11.util.adt.MultiState;
import org.six11.util.adt.SynchronizedQueue;

/**
 * The 'vote for a theme' panel.
 * 
 * @author Gabe Johnson <johnsogg@cmu.edu>
 */
public class ThemePanel extends JPanel {

  protected MultiState state;
  protected JLabel instructions;
  protected JPanel list;
  private ActionListener voteAction;

  /**
   * @param multiState
   */
  public ThemePanel(MultiState ms) {
    this.state = ms;
    setBackground(Color.WHITE);
    state.addChangeListener(ClientStateNames.K_THEME_LIST, new PropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent evt) {
        bug("Got property change event for K_THEME_LIST, attempting to rebuild the ui...");
        rebuildList();
      }

    });
    voteAction = new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
        vote(ev.getActionCommand());
      }
    };
    instructions = new JLabel("Pick a theme!");
    list = new JPanel();
    list.setLayout(new GridLayout(0, 1));
    setLayout(new BorderLayout());
    add(instructions, BorderLayout.NORTH);
    add(list, BorderLayout.CENTER);
    rebuildList();
  }

  private void vote(String id) {
    // change the local accounting, including the current vote, if any.
    for (ThemeChoice tc : getChoices()) {
      tc.setMyChoice(tc.getId().equals(id));
    }
    Message msg = new Message("game");
    msg.addParam("operation", "themeVote");
    msg.addParam("themeOptionID", id);
    SynchronizedQueue<Message> q = (SynchronizedQueue<Message>) state
        .getValue(ClientStateNames.K_TRANSMIT_QUEUE);
    q.add(msg);
  }

  private void bug(String what) {
    Debug.out("ThemePanel", what);
  }

  @SuppressWarnings("unchecked")
  private List<ThemeChoice> getChoices() {
    return (List<ThemeChoice>) state.getValue(ClientStateNames.K_THEME_LIST);
  }

  public void rebuildList() {
    List<ThemeChoice> themeChoices = getChoices();
    Collection<ThemeChoice> sortedChoices = new TreeSet<ThemeChoice>(ThemeChoice.comparator());
    sortedChoices.addAll(themeChoices);
    list.removeAll();
    for (ThemeChoice t : sortedChoices) {
      list.add(makeThemeChoiceItem(t));
    }
    if (sortedChoices.isEmpty()) {
      list.add(new JLabel("No theme information is available."));
    }
    revalidate();
  }

  private JComponent makeThemeChoiceItem(ThemeChoice t) {
    // TODO: eventually this should return a different kind of component (e.g. not a JButton)
    JButton ret = new JButton(t.getName() + " (" + t.getVotes() + " votes) "
        + (t.isMyChoice() ? " *" : ""));
    ret.setActionCommand(t.getId());
    ret.addActionListener(voteAction);
    return ret;
  }
}
